from pydantic import BaseModel, Field
from typing import List, TypeVar, Generic, Optional 

# 定义泛型类型变量
T = TypeVar('T')

class DOIItem(BaseModel):
    """DOI项目的强类型模型"""
    
    task_id: str = Field(description="任务唯一标识符，使用UUID格式")
    doi: str = Field(description="DOI标识符，例如：10.1000/xyz123")
    authors: List[str] = Field(default=[], description="作者列表，包含所有作者的姓名")
    year: str = Field(default="", description="发表年份")
    status: str = Field(
        default="pending", 
        description="处理状态：pending(等待中), downloading(下载中), success(成功), error(失败)"
    )
    title: str = Field(default="", description="文章标题")
    journal: str = Field(default="", description="期刊名称")
    abstract: str = Field(default="", description="文章摘要")
    pdf_url: str = Field(default="", description="PDF文件的下载链接")
    original_index: int = Field(description="在原始上传文件中的索引位置")

class DOITask(BaseModel):
    task_id: str = Field(description="任务唯一标识符，使用UUID格式")
    client_id: str = Field(description="客户端标识符，用于区分不同的客户端")
    status: str = Field(
        default="pending", 
        description="任务状态：pending(等待中), processing(处理中), completed(已完成), failed(失败)"
    )
    total_dois: int = Field(description="任务中DOI的总数量")
    success_dois: int = Field(default=0, description="成功处理的DOI数量")
    completed_dois: int = Field(default=0, description="已完成处理的DOI数量")
    failed_dois: int = Field(default=0, description="处理失败的DOI数量")
    start_time: str = Field(default="", description="任务开始时间，格式：YYYY-MM-DD HH:MM:SS")
    end_time: str = Field(default="", description="任务结束时间，格式：YYYY-MM-DD HH:MM:SS")
    file_name: str = Field(default="", description="上传文件的名称")
    dois: List[DOIItem] = Field(default=[], description="任务中包含的DOI列表")
    download_url:str=Field(default="", description="所有PDF下载链接")

class DOIResponse(BaseModel, Generic[T]):
    message: str = Field(description="响应消息，用于向客户端传达操作结果")
    status: str = Field(description="响应状态：success(成功), error(错误)")
    data: Optional[T] = Field(description="响应数据，使用泛型T允许不同类型的数据")

class PaginatedResponse(BaseModel, Generic[T]):
    """分页响应模型"""
    message: str = Field(default="",description="响应消息")
    status: str = Field(description="响应状态：success(成功), error(错误)")
    page: int = Field(description="当前页码")
    pageSize: int = Field(description="每页条数")
    total: int = Field(description="总记录数")
    totalPages: int = Field(description="总页数")
    items: List[T] = Field(description="数据列表")

class DOIInputRequest(BaseModel): 
    dois: str = Field(description="多个DOI，每行一个，用于手动输入DOI的场景")
    client_id:str= Field(default=None, description="客户端标识符，可选，用于区分不同的客户端")
    
 
 
class JiangSuInputRequest(BaseModel): 
    url: str = Field(description="网址")
    client_id:str= Field(default=None, description="客户端标识符，可选，用于区分不同的客户端")
    
class YLQXBNInputRequest(BaseModel):
    year: str = Field(description="年份，例如：2023")      
    number: str = Field(description="起始号：000",default="000")       
    type: str = Field(description="类型，例如：械备")      
    category:str= Field(description="类别")
    url: str = Field(description="网址")
    page:int= Field(description="页码",default=1) 
    is_single_page:bool= Field(description="是否是单页",default=False)
    is_single_rang:bool= Field(description="是否是单范围",default=False)
    client_id:str= Field(default=None, description="客户端标识符，可选，用于区分不同的客户端")
    
    
class YLQXBNDetailInputRequest(BaseModel):
    url: str = Field(default=None, description="网址")
    client_id:str= Field(default=None, description="客户端标识符，可选，用于区分不同的客户端")
    


class SortField(BaseModel):
    """排序字段模型"""
    field: str = Field(description="排序字段名")
    order: str = Field(default="asc", description="排序顺序：asc或desc")

class PaginationParams(BaseModel):
    page: int = Field(default=1, description="页码")
    pageSize: int = Field(default=10, description="每页条数")
    sortFields: List[SortField] = Field(default=None, description="排序字段列表")
    
    @property
    def offset(self) -> int:
        """计算偏移量：(页码 - 1) * 每页条数"""
        return (self.page - 1) * self.pageSize
    
    @property
    def limit(self) -> int:
        """获取每页限制条数"""
        return self.pageSize
    
    


class DataBaseProjectDoingInputRequest(PaginationParams):
    keyword: str = Field(default=None, description="关键字")
    class1: List[str] = Field(default=None, description="分类界定")
    class2: List[str] = Field(default=None, description="研究领域")
    subject: List[str] = Field(default=None, description="临床科室")
    center_name: List[str] = Field(default=None, description="研究中心")
    
    
    @property
    def orderBy(self):
        """转换为数据库服务需要的order_by格式"""
        if not self.sortFields:
            return None
        
        if len(self.sortFields) == 1:
            sort_field = self.sortFields[0]
            return (sort_field.field, sort_field.order)
        else:
            return [(sf.field, sf.order) for sf in self.sortFields]
        
        
 